<?php

namespace App\Libs\Top;


use DingRobot;
use Log;
use Symfony\Component\Console\Exception\LogicException;

class TopLibrary
{
    private $client;
    private $sessions;
    private $currentSession;

    public function __construct()
    {
        require_once "TopSdk.php";

        $appkey = config('store.TOP_APP_KEYS.LJWY', '');
        $secret = env('TOP_SECRET_'.$appkey);
        $this->sessions = config("store.TOP_SESSION_KEYS.{$appkey}", []);
        $this->client = new \TopClient;
        $this->client->appkey = $appkey;
        $this->client->secretKey = $secret;
    }

    /**
     * @param $appKey
     */
    public function setAppkey($appKey)
    {
        $secret = env('TOP_SECRET_'.$appKey);
        if (!is_null($secret)) {
            $this->client->appkey = (string)$appKey;
            $this->client->secretKey = $secret;
            $this->sessions = config("store.TOP_SESSION_KEYS.{$appKey}", []);
        } else {
            throw new LogicException("appkey {$appKey} 未找到对应的配置信息!");
        }
    }

    /**
     * @param $key
     * @return bool
     */
    public function setCurrentSession($key)
    {
        $currentSession = data_get($this->sessions, $key);
        if (is_null($currentSession)) {
            Log::error("未知的session索引{$key}!");

            return false;
        }

        $this->currentSession = $currentSession;

        return true;
    }

    public function getOssToken()
    {
        $appkey = env('TOP_APPKEY_INTERACTIVE');
        $secret = env('TOP_SECRET_INTERACTIVE');
        $c = new \TopClient;
        $c->appkey = $appkey;
        $c->secretKey = $secret;

        $req = new \AlibabaWtCifCoopOsstokenGetRequest;
        $req->setAppName("suoruanapp");
        $req->setSource("AliTelecom");
        $req->setBiz("ShuoRuan");

        $resp = $c->execute($req);

        return $resp;
    }

    /**
     * @param $credential
     * @param $mixNick
     * @param $amount
     * @param $mobile
     */
    public function couponCreateByMixNick($credential, $mixNick, $amount, $mobile)
    {
        $this->couponCreate($credential, $mixNick, $amount, $mobile, true);
    }

    /**
     * @param $credential 兑换凭据, 通常是支付流水号, 兑换码
     * @param $tbUsername 淘宝用户名 或 混淆的淘宝用户名
     * @param $amount 兑换金额(分)
     * @param $account 手机号码
     * @param $session TaeSession
     * @return boolean 是否兑换成功
     */
    public function couponCreate($credential, $nick, $amount, $account = 'rocky', $isMixNick = false)
    {

        \Log::info('兑换天猫购物券', func_get_args());
        //        // mock start
        //        if (!\App::environment('product')) {
        //            switch ($amount) {
        //                case 100:
        //                case 1000:
        //                    throw new \LogicException('淘宝昵称不存在', 10);
        //                    break;
        //                case 1000:
        //                case 2000:
        //                case 5000:
        //                case 10000:
        //                    return true;
        //                    break;
        //            }
        //        }
        //        // mock end

        $appkey = env('TOP_APPKEY_INTERACTIVE');
        $secret = env('TOP_SECRET_INTERACTIVE');

        $c = new \TopClient;
        $c->appkey = $appkey;
        $c->secretKey = $secret;
        $sessionKey = '6202a27f4257931539c9adc0ddf4aee3b90ZZ56050fa0ff2690965891';

        if ($isMixNick) {
            //doc: http://open.taobao.com/docs/api.htm?apiId=27668
            $req = new \AlibabaAlicomExchangeCreatebymixnickRequest;
        } else {
            //doc: http://open.taobao.com/docs/api.htm?apiId=27560
            //doc: http://open.taobao.com/doc2/apiDetail.htm?apiId=29683&scopeId=343
            $req = new \AlibabaAlicomOrderExchangeCreateRequest;
        }

        $exchange_model = new \ExchangeModel;
        $exchange_model->amount = $amount;
        $exchange_model->order_no = $credential;
        $exchange_model->nick = $nick;
        $req->setExchangeModel(json_encode($exchange_model));
        $resp = $c->execute($req, $sessionKey);

        //CreatebymixnickReques 和 CreateRequest 的返回值格式不一样, 先转换成同样的格式
        foreach (data_get($resp, 'result', []) as $key => $val) {
            switch ($key) {
                case 'code':
                    $key = 'return_code';
                    break;
                case 'success':
                    $key = 'is_success';
                    break;
            }
            data_set($resp, $key, $val);
        }

        $is_success = data_get($resp, 'is_success');
        if (!$is_success) {
            if ($amount > 1) {
                $message['信息'] = '天猫兑换购物券接口异常';
                $message['请求'] = ['凭据' => $credential, '淘宝号' => $nick, '金额' => $amount / 100];
                $message['结果'] = $resp;
                DingRobot::send('outer_api', $message);
            }
            throw new \LogicException(data_get($resp, 'desc', '天猫兑换购物券接口异常'), 10);
        }
        $message['信息'] = '天猫兑换购物券成功';
        $message['请求'] = ['凭据' => $credential, '淘宝号' => $nick, '金额' => $amount / 100];
        $message['结果'] = $resp;
        DingRobot::send('tmall_coupon', $message);

        return $is_success;
    }

    public function isTbUsernameExist($tbUsername)
    {
        //        // mock. 淘宝昵称中带rocky的, 都是不存在的.
        //        if (!\App::environment('product')) {
        //            return (strpos($tbUsername, 'rocky') === false);
        //        }
        //        // mock end
        $appkey = env('TOP_APPKEY_INTERACTIVE');
        $secret = env('TOP_SECRET_INTERACTIVE');
        $c = new \TopClient;
        $c->appkey = $appkey;
        $c->secretKey = $secret;
        $req = new \AlibabaWtOrderExchangePartnerChecktbuserRequest;
        $out_exchange_model = new \OutExchangeModel;
        $out_exchange_model->amount = "1000";
        $out_exchange_model->nick = $tbUsername;
        $out_exchange_model->out_id = microtime(true);
        $out_exchange_model->account = 'rocky';
        $out_exchange_model->biz_type = "15";
        //$out_exchange_model->partner = env('TOP_COUPON_PARTNER');
        $out_exchange_model->partner = 'test';
        $out_exchange_model->from = "portal";
        $out_exchange_model->coupon_face = "1000";
        $req->setOutExchangeModel(json_encode($out_exchange_model));
        $resp = $c->execute($req);

        return data_get($resp, 'model');
    }

    /**
     * 创建天机厅交易, 返回交易token.
     * token在天机厅交易时序中的位置, 见文档 http://rocky.zhuopu.net:8090/pages/viewpage.action?pageId=6029343#id-天机厅-时序
     * @param $mixUserId 买家混淆user ID
     * @param $itemId 商品ID
     * @param $orderSkuId 订单sku的数据库流水号
     * @param $skuPrice 用户选中SKU的价格，可支持两位小数，单位（元）
     * @param $sku 用户选中SKU
     * @return mixed
     */
    public function tradeCreate($mixUserId, $itemId, $orderSkuId, $skuPrice, $sku = [], $mobile = '')
    {
        if ($skuPrice <= 0) {
            throw new \LogicException('Invalid arguments:total_price', 41);
        }

        // mock start
        if (!\App::environment('product')) {
            return '739D0FCDAF76903BC2D56D0DA81B30D7';
        }
        // mock end

        $appkey = env('TOP_APPKEY_OPEN_TRADE');
        $secret = env('TOP_SECRET_OPEN_TRADE');
        $pluginId = 200;

        //todo 从接口中获取appkey，然后注入到当前类中. secret和pluginId 通过appkey在config中获取。
        if ('549932045967' == $itemId) {
            $appkey = '23781790';
            $secret = env('TOP_SECRET_'.$appkey);
            $pluginId = 243;
        }

        $c = new \TopClient;
        $c->appkey = $appkey;
        $c->secretKey = $secret;

        //淘宝接口 alibaba.aliqin.trade.create (阿里通信运营商订单信息创建) http://open.taobao.com/docs/api.htm?apiId=28029
        $req = new \AlibabaAliqinTradeCreateRequest;

        $ex_property = new \Exproperty;
        $ex_property->service_type = "depositFee";
        $ex_property->package_name = $sku['合约名'];
        $ex_property->package_details = $sku['合约详情'];
        $ex_property->operators = $sku['运营商'];
        $ex_property->province = $sku['归属地'];
        $ex_property->monthly_fee = $sku['月租'];

        //$ex_property->broadband_rate="100M";
        //$ex_property->effective_date="2017年11月11号零点";
        //$ex_property->contract_period="2年";
        //$ex_property->broadband_account="宽带账号";

        $ex_property->mobile = $mobile;
        //$ex_property->id_number="身份证号";
        //$ex_property->name="机主姓名";
        //$ex_property->source="detail";
        //$ex_property->installation_address="浙江杭州xxxxx";

        $ex_property->package_price = $skuPrice;
        $ex_property->preferential_info = $sku['优惠信息'];
        //$ex_property->attach_info="sku:898";

        $req->setExProperty(json_encode($ex_property));
        $req->setMixUserId($mixUserId);
        $req->setItemId($itemId);
        $req->setTotalPrice("$skuPrice");
        $req->setPluginInstanceId("$pluginId");
        $req->setMerchantOrderId(time().$orderSkuId);
        //$req->setExpiryDate("2016-07-29 12:12:12");

        $resp = $c->execute($req);

        if (!$token = data_get($resp, 'trade_extend_token')) {
            $message['信息'] = '天猫 创建天机厅交易 接口异常';
            $message['请求'] = func_get_args();
            $message['结果'] = $resp;
            DingRobot::send('development', $message);
            throw new \LogicException(data_get($resp, 'msg'), data_get($resp, 'code'));
        }

        return $token;
    }

    /**
     * 创建天机厅交易, 返回交易token
     * @param $mixUserId 买家混淆user ID
     * @param $itemId 商品ID
     * @param $orderSkuId 订单sku的数据库流水号
     * @param $skuPrice 用户选中SKU的价格，可支持两位小数，单位（元）
     * @param array $exProperty 扩展信息
     * @return mixed|string
     */
    public function tradeCreate1($mixUserId, $itemId, $orderSkuId, $skuPrice, array $exProperty = [])
    {
        if ($skuPrice <= 0) {
            throw new \LogicException('Invalid arguments:total_price', 41);
        }

        // mock start
        if (\App::environment('testing')) {
            return '739D0FCDAF76903BC2D56D0DA81B30D7';
        }
        // mock end

        // 从itemid配置中获取appkey
        if (!$appkey = config("store.TIANJI_ITEMS.{$itemId}.appKey")) {
            throw new \LogicException("appKey $appkey not found", 11);
        }
        if (!$pluginId = config("store.TIANJI_ITEMS.{$itemId}.pluginId")) {
            throw new \LogicException("pluginId $pluginId not found", 12);
        }
        if (!$secret = env("TOP_SECRET_{$appkey}")) {
            throw new \LogicException("secret $secret not found", 13);
        }


        $c = new \TopClient;
        $c->appkey = $appkey;
        $c->secretKey = $secret;

        //淘宝接口 alibaba.aliqin.trade.create (阿里通信运营商订单信息创建) http://open.taobao.com/docs/api.htm?apiId=28029
        $req = new \AlibabaAliqinTradeCreateRequest;
        $req->setPluginInstanceId("$pluginId");

        $req->setMixUserId($mixUserId);
        $req->setItemId($itemId);
        $req->setMerchantOrderId(time().$orderSkuId);
        $req->setTotalPrice("$skuPrice");

        //创建扩展属性
        $ex_property = $this->createExProperty($exProperty);
        $req->setExProperty(json_encode($ex_property));

        $resp = $c->execute($req);

        if (!$token = data_get($resp, 'trade_extend_token')) {
            $message['信息'] = '天猫 创建天机厅交易 接口异常';
            $message['请求'] = array_merge(func_get_args(), [$appkey, $pluginId, $secret]);
            $message['结果'] = $resp;
            DingRobot::send('development', $message);
            throw new \LogicException(data_get($resp, 'msg'), data_get($resp, 'code'));
        }
        \Log::info("天际厅 创建天机厅交易 返回值", [$resp]);

        return $token;
    }

    private function ding($request, $result)
    {

    }

    /**
     * 创建扩展属性
     * @param array $exProperty
     * @return \Exproperty
     */
    private function createExProperty(array $exProperty)
    {
        $ex_property = new \Exproperty();
        $ex_property->service_type = 'depositFee';

        foreach ($ex_property as $key => $item) {
            if (isset($exProperty[$key])) {
                $ex_property->$key = $exProperty[$key];
            }
        }

        return $ex_property;
    }

    /**
     * 更新备注信息
     * @param $tid
     * @param $msg
     * @param $flag
     * @param bool $reset
     * @return mixed|\ResultSet|\SimpleXMLElement
     */
    public function updateMemo($tid, $msg, $flag, $reset = false)
    {
        \Log::info("更新淘宝订单{$tid}备注: {$msg}-{$flag}");

        $req = new \TradeMemoUpdateRequest;
        $req->setTid((string)$tid);
        if (!empty($msg)) {
            $req->setMemo($msg);
        }
        $req->setFlag((string)$flag);
        $req->setReset($reset);

        $c = $this->client;
        $resp = $c->execute($req, $this->currentSession);

        \Log::info('更新淘宝订单状态返回值:', [$resp]);  //接口返回日志

        return $resp;
    }

    /**
     * 虚拟物流发货
     * @param $oid
     * @return mixed|\ResultSet|\SimpleXMLElement
     */
    public function logisticsDummy($oid)
    {
        $req = new \LogisticsDummySendRequest;
        $req->setTid((string)$oid);

        $c = $this->client;
        $resp = $c->execute($req, $this->currentSession);
        \Log::info('更新淘宝订单状态返回值:', [$resp]);  //接口返回日志

        return $resp;
    }

    /**
     * 获取单个订单信息
     * @param $oid
     * @param null $fields
     * @return mixed|\ResultSet|\SimpleXMLElement
     */
    public function getOrderById($oid, $fields = null)
    {
        $req = new \TradeFullinfoGetRequest;
        if (is_null($fields)) {
            $req->setFields('tid,type,status,payment,orders,seller_flag,seller_memo');
        } else {
            $req->setFields($fields);
        }
        $req->setTid((string)$oid);
        $c = $this->client;
        $resp = $c->execute($req, $this->currentSession);
        \Log::info('更新淘宝订单状态返回值:', [$resp]);  //接口返回日志

        return $resp;
    }

    /**
     * 获取商品信息
     * @param $itemId
     * @param null $fields
     * @return mixed|\ResultSet|\SimpleXMLElement
     */
    public function getSellerItem($itemId, $fields = null)
    {
        $req = new \ItemSellerGetRequest;
        if (is_null($fields)) {
            $req->setFields('num_iid,title,nick,price,approve_status,sku');
        } else {
            $req->setFields($fields);
        }
        $req->setNumIid($itemId);
        $c = $this->client;
        $resp = $c->execute($req, $this->currentSession);
        \Log::info('获取淘宝订单返回值:', [$resp]);  //接口返回日志

        return $resp;
    }

    /**
     * 使用阿里云发送短信验证码
     * @param $mobile
     * @param $code
     * @return bool
     */
    public function aliSendSms($mobile, $code, $type = 'code', $data=[])
    {

        // mock start
        Log::info("阿里云发送短信",[$mobile, $code, $type]);

        if (!\App::environment(['product', 'production'])) {
            ding('development', "手机号 $mobile 验证码 $code 类型 $type");
            return true;
        }
        // mock end

        $params = array();

        // *** 需用户填写部分 ***

        // fixme 必填: 请参阅 https://ak-console.aliyun.com/ 取得您的AK信息
        $accessKeyId = "LTAIEKD9a2TB08bP";
        $accessKeySecret = 'mZvuQk7JWdL2WqSZcgE6C8tklpwws8';

        // fixme 必填: 短信接收号码
        $params["PhoneNumbers"] = $mobile;

        // fixme 必填: 短信签名，应严格按"签名名称"填写，请参考: https://dysms.console.aliyun.com/dysms.htm#/develop/sign
        $params["SignName"] = "微步世界";

        switch ($type) {
            case 'code':
                // fixme 必填: 短信模板Code，应严格按"模板CODE"填写, 请参考: https://dysms.console.aliyun.com/dysms.htm#/develop/template
                $params["TemplateCode"] = "SMS_212700147";

                // fixme 可选: 设置模板参数, 假如模板中存在变量需要替换则为必填项
                $params['TemplateParam'] = Array(
                    "code" => $code,
                );
                break;
            case 'sign_up_success':
                $params["TemplateCode"] = "SMS_195720894";
                break;
            case 'sign_up_success2':
                $params["TemplateCode"] = "SMS_198691779";
                break;
            case 'game_complete':
                $params["TemplateCode"] = "SMS_215338552";
                $params['TemplateParam'] = $data;
                break;
            case 'game_complete_asb':
                $params["TemplateCode"] = "SMS_215338552";
                $params["SignName"] = "奥赛帮赛事";
                $params['TemplateParam'] = $data;
                break;
            default:
                error('未知的短信模板类型', [$type]);
                return false;
        }

        // *** 需用户填写部分结束, 以下代码若无必要无需更改 ***
        if (!empty($params["TemplateParam"]) && is_array($params["TemplateParam"])) {
            $params["TemplateParam"] = json_encode($params["TemplateParam"], JSON_UNESCAPED_UNICODE);
        }

        // 初始化SignatureHelper实例用于设置参数，签名以及发送请求
        $helper = new \SignatureHelper();

        // 此处可能会抛出异常，注意catch
        try {
            $content = $helper->request(
                $accessKeyId,
                $accessKeySecret,
                "dysmsapi.aliyuncs.com",
                array_merge(
                    $params,
                    array(
                        "RegionId" => "cn-hangzhou",
                        "Action"   => "SendSms",
                        "Version"  => "2017-05-25",
                    )
                )
            );
            Log::info("阿里云发送短信返回值", [$content]);

            if (data_get($content, 'Code') != 'OK') {
                return false;
            }

        } catch (\Exception $e) {
            Log::error("阿里云发送短信异常", [$e->getMessage()]);

            return false;
        }

        return true;
    }

    public function aliShopSendSms($shopName, $mobile, $message, $type){

        // mock start
        Log::info("阿里云发送短信",[$shopName, $mobile, $message, $type]);

//        if (!\App::environment(['product', 'production'])) {
//            ding('development', "手机号 $mobile 验证码 $code 类型 $type");
//            return true;
//        }
        // mock end

        $params = array();

        // *** 需用户填写部分 ***

        // fixme 必填: 请参阅 https://ak-console.aliyun.com/ 取得您的AK信息
        $accessKeyId = "LTAIEKD9a2TB08bP";
        $accessKeySecret = env('ALIYUN_SMS_SECRET', '');

        // fixme 必填: 短信接收号码
        $params["PhoneNumbers"] = $mobile;

        // fixme 必填: 短信签名，应严格按"签名名称"填写，请参考: https://dysms.console.aliyun.com/dysms.htm#/develop/sign
        $params["SignName"] = '和沃翼起';

        switch ($type) {
            case 'zyj':
                // fixme 必填: 短信模板Code，应严格按"模板CODE"填写, 请参考: https://dysms.console.aliyun.com/dysms.htm#/develop/template
                $params["TemplateCode"] = "SMS_189033210";

                // fixme 可选: 设置模板参数, 假如模板中存在变量需要替换则为必填项
                $params['TemplateParam'] = Array(
                    "shop_name" => $shopName,
                );
                break;
            case 'zyjzp':
                // fixme 必填: 短信模板Code，应严格按"模板CODE"填写, 请参考: https://dysms.console.aliyun.com/dysms.htm#/develop/template
                $params["TemplateCode"] = "SMS_189505378";

                // fixme 可选: 设置模板参数, 假如模板中存在变量需要替换则为必填项
                $params['TemplateParam'] = Array(
                    "shop_name" => $shopName,
                );
                break;

            default:
                error('未知的短信模板类型', [$type]);
                return false;
        }

        // *** 需用户填写部分结束, 以下代码若无必要无需更改 ***
        if (!empty($params["TemplateParam"]) && is_array($params["TemplateParam"])) {
            $params["TemplateParam"] = json_encode($params["TemplateParam"], JSON_UNESCAPED_UNICODE);
        }

        // 初始化SignatureHelper实例用于设置参数，签名以及发送请求
        $helper = new \SignatureHelper();

        // 此处可能会抛出异常，注意catch
        try {
            $content = $helper->request(
                $accessKeyId,
                $accessKeySecret,
                "dysmsapi.aliyuncs.com",
                array_merge(
                    $params,
                    array(
                        "RegionId" => "cn-hangzhou",
                        "Action"   => "SendSms",
                        "Version"  => "2017-05-25",
                    )
                )
            );
            Log::info("阿里云发送短信返回值", [$content]);

            if (data_get($content, 'Code') != 'OK') {
                return false;
            }

        } catch (\Exception $e) {
            Log::error("阿里云发送短信异常", [$e->getMessage()]);

            return false;
        }

        return true;
    }
}